package com.sangeng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.constant.SystemConstants;
import com.sangeng.constant.enums.AppHttpCodeEnum;
import com.sangeng.domain.core.ResponseResult;
import com.sangeng.domain.dto.UserDto;
import com.sangeng.domain.dto.UserInsertDto;
import com.sangeng.domain.dto.UserListDto;
import com.sangeng.domain.dto.UserUpdateDto;
import com.sangeng.domain.entity.UserRole;
import com.sangeng.domain.vo.*;
import com.sangeng.service.UserRoleService;
import com.sangeng.utils.BeanUtil;
import com.sangeng.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.sangeng.domain.entity.User;
import com.sangeng.mapper.UserMapper;
import com.sangeng.service.UserService;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2025-06-16 15:20:03
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleServiceImpl roleService;

    @Override
    public ResponseResult getUserInfo() {
        User user = getById(SecurityUtils.getUserId());
        UserInfoVo userInfoVo = BeanUtil.copyBean(user, UserInfoVo.class);
        return ResponseResult.okResult(userInfoVo);
    }

    @Override
    public ResponseResult updateUserInfo(UserDto user) {
        User updateUser = BeanUtil.copyBean(user, User.class);
        updateUser.setId(SecurityUtils.getUserId());
        boolean flag = updateById(updateUser);
        if(!flag){
            return ResponseResult.errorResult(AppHttpCodeEnum.UPDATE_USER_ERROR);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult register(User user) {
        if(user.getUserName() == null || user.getPassword() == null
                || user.getEmail() == null || user.getNickName() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 判断用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, user.getUserName());
        if (getOne(queryWrapper) != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.USERNAME_EXIST);
        }

        // 判断邮箱是否存在
        queryWrapper.clear();
        queryWrapper.eq(User::getEmail, user.getEmail());
        if (getOne(queryWrapper) != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.EMAIL_EXIST);
        }

        // 对密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        // 默认添加sex为1
        user.setSex(SystemConstants.USER_SEX_UNKNOWN);
        // 默认头像
        user.setAvatar(SystemConstants.DEFAULT_AVATAR);
        // 保存用户
        save(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult listUsers(UserListDto userListDto) {
        // 创建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(userListDto.getUserName() != null, User::getUserName, userListDto.getUserName())
                .eq(userListDto.getPhonenumber() != null, User::getPhonenumber, userListDto.getPhonenumber())
                .eq(userListDto.getStatus() != null, User::getStatus, userListDto.getStatus());

        // 创建分页条件
        Page<User> page = new Page<>(userListDto.getPageNum(), userListDto.getPageSize());
        Page<User> result = page(page, queryWrapper);

        return ResponseResult.okResult(new PageVo(result.getRecords(), result.getTotal()));
    }

    @Transactional
    @Override
    public ResponseResult registerAdminUser(UserInsertDto userInsertDto) {
        User user = BeanUtil.copyBean(userInsertDto, User.class);
        // 检查各项内容是否为空
        if (user.getUserName() == null || user.getPassword() == null || user.getNickName() ==  null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 检查用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, user.getUserName()).eq(User::getDelFlag, SystemConstants.NOT_DELETED);
        if (getOne(queryWrapper) != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.USERNAME_EXIST);
        }
        // 设置用户类型为管理员
        user.setType(SystemConstants.ADMIN_USER);
        // 对密码进行加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        // 新增用户
        save(user);

        // 新增用户角色表内容
        List<UserRole> userRoleList = userInsertDto.getRoleIds().stream().
                map(roleId -> new UserRole(user.getId(), roleId))
                .toList();
        if(!userRoleList.isEmpty()){
            userRoleService.saveBatch(userRoleList);
        }
        return ResponseResult.okResult();
    }

    @Transactional
    @Override
    public ResponseResult removeUserById(Long id) {
        // 删除用户
        removeById(id);
        // 删除用户角色表内容
        LambdaQueryWrapper<UserRole> query = new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, id);
        userRoleService.remove(query);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserRolesById(Long id) {
        // 获取用户关联角色列表
        List<UserRole> userRoleList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, id));
        List<Long> roleIds = userRoleList.stream()
                .map(UserRole::getRoleId).toList();

        // 获取角色列表
        List<UserRoleVo> roleList = (List<UserRoleVo>)roleService.listAllRole().getData();

        // 获取用户信息
        User user = getById(id);
        UserVo userVo = BeanUtil.copyBean(user, UserVo.class);

        // 封装数据
        return ResponseResult.okResult(new UserRoleInfoVo(roleIds, roleList, userVo));
    }

    @Transactional
    @Override
    public ResponseResult updateUser(UserUpdateDto userUpdateDto, boolean changeStatus) {
        // 更新用户
        updateById(BeanUtil.copyBean(userUpdateDto, User.class));
        if(!changeStatus){
            // 删除用户角色表内容
            LambdaQueryWrapper<UserRole> query = new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userUpdateDto.getId());
            userRoleService.remove(query);
            // 新增用户角色表内容
            List<UserRole> userRoleList = userUpdateDto.getRoleIds().stream().
                    map(roleId -> new UserRole(userUpdateDto.getId(), roleId))
                    .toList();
            if(!userRoleList.isEmpty()){
                userRoleService.saveBatch(userRoleList);
            }
        }
        return ResponseResult.okResult();
    }

}

